package com.hlkj.baojin.utils.bean;

import org.hibernate.validator.HibernateValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * @author liu-zhong-xin
 * @createDate 2018/2/7 0007
 */
public class BeanReflectUtils {
    /**
     * 包含null字段返回false
     *
     * @param obj
     * @return
     * @throws
     */
    public static boolean beanContainNull(Object obj) {
        final Logger logger = LoggerFactory.getLogger(BeanReflectUtils.class);
        boolean flag = true;
        for (Field f : obj.getClass().getDeclaredFields()) {
            f.setAccessible(true);
            logger.info(f.getName());
            try {
                if (f.get(obj) == null) {
                    flag = false;
                    return flag;
                }
            } catch (IllegalAccessException e) {
                logger.error("反射失败", e);
            }
        }
        return flag;
    }

    /**
     * 反射-获取某对象的属性值
     *
     * @param fieldName 字段名称
     * @param o         对象
     * @return Object
     */
    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            //获取方法名
            String getter = "get" + firstLetter + fieldName.substring(1);
            //获取方法对象
            Method method = o.getClass().getMethod(getter);
            //用invoke调用此对象的get字段方法
            Object value = method.invoke(o);
            //返回值
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 使用hibernate的注解来进行验证
     */
    private static Validator validator = Validation
            .byProvider(HibernateValidator.class).configure().failFast(false).buildValidatorFactory().getValidator();

    /**
     * 校验对象，当没有通过校验而且throwException=true时则会抛出异常
     *
     * @param obj            验证对象
     * @param throwException 是否抛出异常
     */
    public static <T> Set<ConstraintViolation<T>> validate(T obj, boolean throwException) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
        if (throwException && constraintViolations.size() > 0) {
            throw new ConstraintViolationException(constraintViolations);
        }
        return constraintViolations;
    }

    /**
     * 校验对象
     *
     * @param obj
     */
    public static <T> Set<ConstraintViolation<T>> validate(T obj) {
        return validate(obj, true);
    }


}
